#ifndef VECTOR3R_H
#define VECTOR3R_H

#include <cassert>
#include <cfloat>
#include <cmath>
#include <iostream>

namespace XYF
{
    using Real = double;

    /**
     * @file: Vector3f.h
     * @author: xingyifan
     * @date: 2023-03-11 19:27
     *
     * @description: 三维向量
     */

    class Vector3f
    {
    protected:
        Real m_x, m_y, m_z;

    public:
        Vector3f(Real x = 0, Real y = 0, Real z = 0);

        Vector3f operator*(Real t) const;
        Vector3f operator/(Real t) const;
        Vector3f operator-(const Vector3f &v) const;
        Vector3f operator+(const Vector3f &v) const;
        bool operator==(const Vector3f &v) const;

        Real x() const;
        Real y() const;
        Real z() const;
        Real &rx();
        Real &ry();
        Real &rz();

        Real r() const;
        Real g() const;
        Real b() const;
        Real &rr();
        Real &rg();
        Real &rb();

        // 输出函数
        friend std::ostream &operator<<(std::ostream &o, const Vector3f &v)
        {
            o << v.x() << " " << v.y() << " " << v.z() << std::endl;
            return o;
        }
    };

    Vector3f linear(Vector3f p1, Vector3f p2, Real t);               // 点线性插值
    Vector3f cross(Vector3f v1, Vector3f v2);                        // 向量叉积
    Vector3f normalize(Vector3f p);                                  // 向量规范化
    Real det(Vector3f v1, Vector3f v2, Vector3f v3);                 // 行列式 (v1 x v2) * v3
    Real length(Vector3f p);                                         // 向量长度
    Real distance(Vector3f p1, Vector3f p2);                         // 计算点的距离
    Real dot(Vector3f v1, Vector3f v2);                              // 向量点积
    bool onLine(Vector3f p1, Vector3f p2, Vector3f p3);              // 判断三点是否共线
    bool onFace(Vector3f p1, Vector3f p2, Vector3f p3, Vector3f p4); // 判断四点是否共面
}

#endif // VECTOR3R_H
